
function WASDecoder(){
	this.TYPE_ALPHA = 0x00;// 前2位
	this.TYPE_ALPHA_PIXEL = 0x20;// 前3位 0010 0000
	this.TYPE_ALPHA_REPEAT = 0x00;// 前3位
	this.TYPE_FLAG = 0xC0;// 2进制前2位 1100 0000
	this.TYPE_PIXELS = 0x40;// 以下前2位 0100 0000
	this.TYPE_REPEAT = 0x80;// 1000 0000
	this.TYPE_SKIP = 0xC0; // 1100 0000
	/** 文件头标记 */
	this.WAS_FILE_TAG = "SP";
	this.TCP_HEADER_SIZE = 12;
	
	
	// Reference Pixel(悬挂点)
	this.refPixelX=null;

	this.refPixelY=null;

	/** 包含动画个数 */
	this.animCount=null;

	/** 动画的帧数 */
	this.frameCount=null;
	
	/** 文件头大小 */
	this.headerSize=null;
	
	/** 原始调色板 */
	this.originPalette=null;
	
	/** 当前调色板 */
	this. palette=null;
	
	/** 精灵宽度 */
	this.width=null;
	/** 精灵高度 */
	this.height=null;

	this.schemeIndexs=null;

	this.sections=null;

	this.frames=[];

	this.randomIn=null;
}

WASDecoder.prototype = {
    constructor: WASDecoder,  //每个函数都有prototype属性，指向该函数原型对象，原型对象都有constructor属性，这是一个指向prototype属性所在函数的指针
    load: function(data){
    	this.randomIn=this.prepareInputStream(data);
    	this.headerSize = this.randomIn.readUnsignedShort();
    	this.animCount = this.randomIn.readUnsignedShort();
    	this.frameCount = this.randomIn.readUnsignedShort();
    	this.width = this.randomIn.readUnsignedShort();
    	this.height = this.randomIn.readUnsignedShort();
    	this.refPixelX = this.randomIn.readUnsignedShort();
    	this.refPixelY = this.randomIn.readUnsignedShort();
		// 读取帧延时信息
		let len = this.headerSize - this.TCP_HEADER_SIZE;
		if (len < 0) {
			throw "帧延时信息错误: " + len;
		}
		let delays = new Array(len);
		for (let i = 0; i < len; i++) {
			delays[i] = this.randomIn.read();
		}

		// 读取调色板
		this.randomIn.seek(this.headerSize + 4);
		this.originPalette=[];
		for (let i = 0; i < 256; i++) {
			this.originPalette[i] = this.randomIn.readUnsignedShort();
		}
		// 复制调色板
		this.palette=this.originPalette.concat();
		// 帧偏移列表
		let frameOffsets = new Array(this.animCount * this.frameCount);
		this.randomIn.seek(this.headerSize + 4 + 512);
		for (let i = 0; i < this.animCount; i++) {
			for (let n = 0; n < this.frameCount; n++) {
				frameOffsets[i * this.frameCount + n] = this.randomIn.readInt();
			}
		}


		// 帧信息
		let frameX, frameY, frameWidth, frameHeight;
		for (let i = 0; i < this.animCount; i++) {
			for (let n = 0; n < this.frameCount; n++) {
				let offset = frameOffsets[i * this.frameCount + n];
				if (offset == 0)
					continue;// blank frame
				this.randomIn.seek(offset + this.headerSize + 4);
				frameX = this.randomIn.readInt();
				frameY = this.randomIn.readInt();
				frameWidth = this.randomIn.readInt();
				frameHeight = this.randomIn.readInt();
				// 行像素数据偏移
				let lineOffsets = new Array(frameHeight);
				for (let l = 0; l < frameHeight; l++) {
					lineOffsets[l] = this.randomIn.readInt();
				}
				// 创建帧对象
				let delay = 1;
				if (i < delays.length) {
					delay = delays[i];
				}
				let frame = new WASFrame(frameX, frameY, frameWidth, frameHeight, delay, offset, lineOffsets);
				this.frames.push(frame);

				// 解析帧数据
				// int[][] pixels = parse(randomIn, offset, lineOffsets,
				// frameWidth, frameHeight);
				// createImage(frameX, frameY, frameWidth, frameHeight, pixels);
			}
		}


	},
    getFrames(){

        return this.frames;

	},
	getFrame:function(index) {
	let frame = this.frames[index];
	try {
		if (frame.getPixels() == null) {
			frame.setPixels(this.parse(frame));
		}
	} catch (e) {
		console.error(e)
		return null;
	}
	if (this.frameCount == 1) {// 修正单帧动画的偏移问题
		return this.createImage(this.refPixelX, this.refPixelY, frame.getWidth(), frame.getHeight(), frame.getPixels());
	} else {
		return this.createImage(frame.getX(), frame.getY(), frame.getWidth(), frame.getHeight(), frame.getPixels());
	}

	}
	,
	parse:function(frame){
		return this.parse_(this.randomIn, frame.getFrameOffset(), frame.getLineOffsets(), frame.getWidth(), frame.getHeight());
	},
	parse_:function(randomIn,frameOffset, lineOffsets, frameWidth,  frameHeight){

			let pixels = new Array(frameHeight*frameWidth);
		let b, x, c;
		let index;
		let count;
			for (let y = 0; y < frameHeight; y++) {
				x = 0;
				randomIn.seek(lineOffsets[y] + frameOffset + this.headerSize + 4);
				while (x < frameWidth) {
					b = randomIn.read();
					switch ((b & this.TYPE_FLAG)) {
						case this.TYPE_ALPHA:
							if ((b & this.TYPE_ALPHA_PIXEL) > 0) {
								index = randomIn.read();
								c = this.palette[index];
								// palette[index]=0;

								pixels[y*frameWidth+ x++] = c + ((b & 0x1F) << 16);
							} else if (b != 0) {// ???
								count = b & 0x1F;// count
								b = randomIn.read();// alpha
								index = randomIn.read();
								c = this.palette[index];
								// palette[index]=0;

								for (let i = 0; i < count; i++) {
									pixels[y*frameWidth+ x++] = c + ((b & 0x1F) << 16);
								}
							} else {// block end
								if (x > frameWidth) {
									console.error("block end error: [" + y + "][" + x + "/" + frameWidth + "]");
									continue;
								} else if (x == 0) {
									// System.err.println("x==0");
								} else {
									x = frameWidth;// set the x value to break the
									// 'while' sentences
								}
							}
							break;
						case this.TYPE_PIXELS:
							count = b & 0x3F;
							for (let i = 0; i < count; i++) {
							index = randomIn.read();
							pixels[y*frameWidth+ x++] = this.palette[index] + (0x1F << 16);
							// palette[index]=0;

						}
							break;
						case this.TYPE_REPEAT:
							count = b & 0x3F;
							index = randomIn.read();
							c = this.palette[index];
							// palette[index]=0;

							for (let i = 0; i < count; i++) {
							pixels[y*frameWidth+ x++] = c + (0x1F << 16);
						}
							break;
						case this.TYPE_SKIP:
							count = b & 0x3F;
							x += count;
							break;
					}
				}
				if (x > frameWidth)
					console.log("block end error: [" + y + "][" + x + "/" + frameWidth + "]");
			}
			return pixels;


	},
	createImage:function (x,  y,  frameWidth,  frameHeight,  pixels) {
		let image = new BufferedImage(this.width, this.height,
				BufferedImage.TYPE_INT_ARGB);
			this.draw(pixels, image, this.refPixelX - x, this.refPixelY - y, frameWidth,
				frameHeight);
			return image;
	},
	draw:function(pixels, image,  x,  y,  w,  h) {
	let iArray = new Array(4);
	for (let y1 = 0; y1 < h && y1 + y < this.height; y1++) {
		for (let x1 = 0; x1 < w && x1 + x < this.width; x1++) {
			// red 5
			iArray[0] = ((pixels[y1*w +x1] >>> 11) & 0x1F) << 3;
			// green 6
			iArray[1] = ((pixels[y1*w +x1] >>> 5) & 0x3f) << 2;
			// blue 5
			iArray[2] = (pixels[y1*w +x1] & 0x1F) << 3;
			// alpha 5
			iArray[3] = ((pixels[y1*w +x1] >>> 16) & 0x1f) << 3;
			// iArray[3] = ((pixels[y1][x1] >>> 16) & 0x1f) *0xff/0x1f;
			// if(iArray[3]>0)iArray[3] += 7;
			try {
				image.draw(x1 + x, y1 + y,iArray);
				//raster.setPixel(x1 + x, y1 + y, iArray);
			} catch ( e) {
				console.error("%s: x=%s,y=%s,pixel=[%s,%s,%s,%s]\n", e, x1 + x, y1 + y, iArray[0],
					iArray[1], iArray[2], iArray[3]);
				// e.printStackTrace();
			}
		}
	}
}
	,
	prepareInputStream:function(data){
		const buf = 2;
		const randomIn = new RandomAcessInputStream(data,buf);
		let flag =new BytesArrayUtil(data.slice(0,2)).toString();
		if (!this.WAS_FILE_TAG===flag) {

			throw "文件头标志错误:" + flag;
		}
		randomIn.seek(2);
		return randomIn;
	}
}
 